package com.calendar.day;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Vector;

import com.calendar.add.AddView;
import com.calendar.backend.Event;
import com.calendar.backend.Events;
import com.calendar.backend.Help;
import com.calendar.event.EventView;
import com.calendar.month.CalendarView;
import com.calendar.widget.R;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.gesture.Gesture;
import android.gesture.GestureLibraries;
import android.gesture.GestureLibrary;
import android.gesture.GestureOverlayView;
import android.gesture.Prediction;
import android.gesture.GestureOverlayView.OnGesturePerformedListener;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.ContextMenu;
import android.view.Display;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.WindowManager;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnCreateContextMenuListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.AbsoluteLayout;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;

public class DayView extends Activity implements Button.OnClickListener, OnGesturePerformedListener {

	private static final int HOUR_LABEL_WIDTH = 50;
	private static final int HOUR_LABEL_HEIGHT = 100;
	private static final int HOUR_LABEL_COLOR = Color.GRAY;
	private static final int HOUR_LABEL_TEXT_COLOR = Color.WHITE;
	private static final long MILLI_IN_DAY = 86400000;
	private static final long MILLI_IN_HOUR = 3600000;

	public static final int MENU_MONTH = Menu.FIRST + 1;
	public static final int MENU_ADD = Menu.FIRST + 2;
	public static final int MENU_SETTINGS = Menu.FIRST + 3;
	public static final int MENU_EXIT = Menu.FIRST + 4;
	public static final int MENU_HELP = Menu.FIRST + 5;
	
	private Vector<com.calendar.backend.Event> events = null;
	
	Calendar cal;
	
	Button eventBut[];
	int monthValue;
	int dayValue;
	int yearValue;

	boolean leapYear = false;
	int dayFinal = 0;
	GestureLibrary mLibrary;

	private CharSequence times[] = {

			"12 am",
			"1 am",
			"2 am",
			"3 am",
			"4 am",
			"5 am",
			"6 am",
			"7 am",
			"8 am",
			"9 am",
			"10 am",
			"11 am",
			"12 pm",
			"1 pm",
			"2 pm",
			"3 pm",
			"4 pm",
			"5 pm",
			"6 pm",
			"7 pm",
			"8 pm",
			"9 pm",
			"10 pm",
			"11 pm",
	};

	int[] monthTable = new int[12];
	String[] months = new String[12];

	/** Called when the activity is first created. */
	@SuppressWarnings("deprecation")
	@Override
	public void onCreate( Bundle savedInstanceState ) {

		super.onCreate( savedInstanceState );
		setContentView(R.layout.day_view);

		//		ScrollView scroll = (ScrollView) findViewById(R.id.scrollView1);

		monthTable[0] = 0;
		monthTable[1] = 3;
		monthTable[2] = 3;
		monthTable[3] = 6;
		monthTable[4] = 1;
		monthTable[5] = 4;
		monthTable[6] = 6;
		monthTable[7] = 2;
		monthTable[8] = 5;
		monthTable[9] = 0;
		monthTable[10] = 3;
		monthTable[11] = 5;
		
		months[0] = "January";
		months[1] = "February";
		months[2] = "March";
		months[3] = "April";
		months[4] = "May";
		months[5] = "June";
		months[6] = "July";
		months[7] = "August";
		months[8] = "September";
		months[9] = "October";
		months[10] = "November";
		months[11] = "December";

		LinearLayout mainLayout = (LinearLayout) findViewById(R.id.LinearLayout01);
		LinearLayout allDayLayout = new LinearLayout( this );
		final ScrollView scroll = new ScrollView(this);
		double firstEvent = 24.0;

		allDayLayout.setOrientation(LinearLayout.VERTICAL);
		allDayLayout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));

		scroll.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));

		AbsoluteLayout components = new AbsoluteLayout( this );
		components.setBackgroundColor( Color.WHITE );

		//Get the day that this is from the when the user clicks on the monthview
		//Use these values to get data from calendar
		//day is day of the month ex. 26
		//month is the month starting at 0 for January
		//Year example format is 2012
		cal = Calendar.getInstance();

		Bundle extras = getIntent().getExtras();
		if (extras != null) {
			dayValue = extras.getInt("day");
			yearValue = extras.getInt("year");
			monthValue = extras.getInt("month"); //cal.get(Calendar.MONTH);
		}

		//	Load events.
		cal = Calendar.getInstance();
		cal.set(yearValue, monthValue, dayValue, 0, 0, 0);
		Events eventFinder = new Events();
		//new Event(true, getBaseContext(),"",1 + "", "Test Event", "bah", "location", cal.getTimeInMillis(), cal.getTimeInMillis() + 3600000, false, false);
		events = eventFinder.findEvents(getBaseContext(), cal.getTimeInMillis() + 1000, cal.getTimeInMillis() + MILLI_IN_DAY - 1000);

		//	Set the title.
		SimpleDateFormat dateFormat = new SimpleDateFormat("EEEE MMMM d, yyyy");
		this.setTitle(dateFormat.format(cal.getTime()));
		
		//	Add the hour labels.
		for( int i = 0; i < times.length; i++ ) {

			TextView time = new TextView( this );
			time.setText( times[i] );
			time.setGravity( Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL );
			time.setBackgroundColor( HOUR_LABEL_COLOR );
			time.setTextColor(HOUR_LABEL_TEXT_COLOR);
			components.addView( time, new AbsoluteLayout.LayoutParams( HOUR_LABEL_WIDTH,
					HOUR_LABEL_HEIGHT,
					0,
					HOUR_LABEL_HEIGHT * i ) );
		}

		//	Draw a line between the labels and the events.
		TextView verticalLine = new TextView( this );
		verticalLine.setBackgroundColor( Color.BLACK );
		components.addView( verticalLine, new AbsoluteLayout.LayoutParams( 1,
				times.length * HOUR_LABEL_HEIGHT,
				HOUR_LABEL_WIDTH,
				0 ) );

		//	Add lines to break everything up.
		for( int i = 1; i < times.length; i++ ) {

			Display display = ( (WindowManager)getSystemService( Context.WINDOW_SERVICE ) ).getDefaultDisplay();

			TextView line = new TextView( this );
			line.setBackgroundColor( Color.BLACK );
			components.addView( line, new AbsoluteLayout.LayoutParams( display.getWidth(),
					1,
					0,
					HOUR_LABEL_HEIGHT * i ) );
		}

		//	Detect concurrent events.
		for( int i = 0; i < events.size(); i++ ) {

			if( !events.get(i).getAllDay() ) {

				//	Find conflicts with previously process events.
				for( int j = 0; j < i; j++ ) {

					if( !events.get(j).getAllDay() ) {

						double e0Start = convertTime(events.get(i).getStartTime());
						double e0End = convertTime(events.get(i).getEndTime());
						double e1Start = convertTime(events.get(j).getStartTime());
						double e1End = convertTime(events.get(j).getEndTime());

						if( ( ( e0Start < e1Start ) && ( e1Start < e0End ) ) ||
								( ( e1Start < e0Start ) && ( e0Start < e1End ) ) ) {

							//	Events overlap.
							if( events.get(j).concurrentEvents == null ) {

								//	This is the first time the other event has been in a conflict.
								events.get(j).concurrentEvents = new Vector<com.calendar.backend.Event>();
								events.get(j).concurrentEvents.add( events.get(j) );
							}

							//	Add this event to the list of conflicts.
							events.get(i).concurrentPos = events.get(j).concurrentEvents.size();
							events.get(i).concurrentEvents = events.get(j).concurrentEvents;
							events.get(i).concurrentEvents.add( events.get(j) );

							break;
						}
					}
				}
			}
		}

		//Add the events.
		eventBut = new Button[events.size()];
		for( int i = 0; i < events.size(); i++ ) {

			Display display = ( (WindowManager)getSystemService( Context.WINDOW_SERVICE ) ).getDefaultDisplay();

			eventBut[i] = new Button( this );
			eventBut[i].setBackgroundColor( events.get(i).getColor() );
			eventBut[i].setTextColor(Color.WHITE);
			eventBut[i].setText( events.get(i).getEventTitle() );
			//event.setOnClickListener( events[i].listener );

			if( events.get(i).getAllDay()) {

				allDayLayout.addView(eventBut[i]);

			} else {

				int width = display.getWidth() - HOUR_LABEL_WIDTH;
				int xPos = HOUR_LABEL_WIDTH;

				if( events.get(i).concurrentEvents != null ) {

					width /= events.get(i).concurrentEvents.size();
					xPos += events.get(i).concurrentPos * width;
				}

				components.addView(eventBut[i], new AbsoluteLayout.LayoutParams(width,
						(int)(convertDuration(events.get(i).getLength()) * HOUR_LABEL_HEIGHT),
						xPos,
						(int)(convertTime(events.get(i).getStartTime()) * HOUR_LABEL_HEIGHT)));

				//	Draw a boarder around the event.
				TextView top = new TextView( this );
				TextView bottom = new TextView( this );
				TextView left = new TextView( this );
				TextView right = new TextView( this );

				top.setBackgroundColor( Color.BLACK );
				bottom.setBackgroundColor( Color.BLACK );
				left.setBackgroundColor( Color.BLACK );
				right.setBackgroundColor( Color.BLACK );

				components.addView( top, new AbsoluteLayout.LayoutParams( width,
						1,
						xPos,
						(int)( convertTime(events.get(i).getStartTime()) * HOUR_LABEL_HEIGHT ) ) );
				components.addView( bottom, new AbsoluteLayout.LayoutParams( width,
						1,
						xPos,
						(int)( convertTime(events.get(i).getEndTime()) * HOUR_LABEL_HEIGHT ) ) );
				components.addView( left, new AbsoluteLayout.LayoutParams( 1,
						(int)( convertDuration(events.get(i).getLength()) * HOUR_LABEL_HEIGHT ),
						xPos,
						(int)( convertTime(events.get(i).getStartTime()) * HOUR_LABEL_HEIGHT ) ) );
				components.addView( right, new AbsoluteLayout.LayoutParams( 1,
						(int)( convertDuration(events.get(i).getLength()) * HOUR_LABEL_HEIGHT ),
						xPos + width,
						(int)( convertTime(events.get(i).getStartTime()) * HOUR_LABEL_HEIGHT ) ) );
				
				if(convertTime(events.get(i).getStartTime()) < firstEvent)
					firstEvent = convertTime(events.get(i).getStartTime());

			}
			
			final CharSequence tempName = events.get(i).getEventTitle();
			final long tempTime = events.get(i).getStartTime();
			final long tempLength = events.get(i).getLength();
			final String eventID = events.get(i).getEventID();

			eventBut[i].setOnClickListener(new View.OnClickListener() {
				public void onClick(View v) {
					newActivity(tempName, tempTime, tempLength, eventID);
				}

			});
			
//			registerForContextMenu(eventBut[i]);
			final int event = i;
			eventBut[i].setOnCreateContextMenuListener(new OnCreateContextMenuListener() {
				public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
					
					menu.setHeaderTitle(((Button)v).getText());
					menu.add(0, event, 0, "Delete Event");
				}

			});
			
			
		}

		scroll.addView(components);
		mainLayout.addView(allDayLayout);
		mainLayout.addView(scroll);

		firstEvent -= 1.0;
		
		if( firstEvent < 0.0 )
			firstEvent = 0.0;
		
		if(events.size() == 0)
			firstEvent = 8.0;
		
		final int scrollToPosition = (int)(firstEvent * HOUR_LABEL_HEIGHT);
		scroll.post(new Runnable() { 
		    public void run() { 
		        scroll.scrollTo(0, scrollToPosition); 
		    } 
		}); 

		GestureOverlayView gestures = (GestureOverlayView) findViewById(R.id.gestures);
		gestures.addOnGesturePerformedListener(this);

		mLibrary = GestureLibraries.fromRawResource(this, R.raw.gestures);
		if (!mLibrary.load()) {
			finish();
		}
	}

	public void onBackPressed(){
		Intent myIntent = new Intent(getBaseContext(), CalendarView.class);
		startActivityForResult(myIntent, 0);
		this.finish();
	}
	
	public boolean onContextItemSelected(MenuItem item) {
		
		if(item.getTitle() == "Delete Event") {
		
			events.get(item.getItemId()).deleteEvent();
			
			Intent myIntent = new Intent(getBaseContext(), DayView.class);
			myIntent.putExtra("day", dayValue);
			myIntent.putExtra("month", monthValue);
			myIntent.putExtra("year", yearValue);
			startActivityForResult(myIntent, 0);
			this.finish();
			
		}
		
		return true;
	}

	//Goes to the eventView from this view
	public void newActivity(CharSequence name, long start, long length, String eventID){
		Intent myIntent = new Intent(getBaseContext(), AddView.class);
		myIntent.putExtra("day", dayValue);
		myIntent.putExtra("month", monthValue);
		myIntent.putExtra("year", yearValue);
		myIntent.putExtra("eventID", eventID);
		startActivityForResult(myIntent, 0);
		this.finish();
	}

	public void onClick(View arg0) {		
	}

	public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {
		ArrayList<Prediction> predictions = mLibrary.recognize(gesture);

		// We want at least one prediction
		if (predictions.size() > 0 && predictions.get(0).score > 1.0
				&& gesture.getStrokesCount() > 1) {
			String what = "";
			for (int i = 0; i < predictions.size(); i++) {
				if (predictions.get(i).name.equals("Add1")
						|| predictions.get(i).name.equals("Add2")
						|| predictions.get(i).name.equals("Add3")
						|| predictions.get(i).name.equals("Add4")
						|| predictions.get(i).name.equals("Add5")
						|| predictions.get(i).name.equals("Add6")
						|| predictions.get(i).name.equals("Add7")
						|| predictions.get(i).name.equals("Add8")
						|| predictions.get(i).name.equals("Agenda")) {
					what = predictions.get(i).name;
					break;
				}
			}
			if(what.equals("Add1") || what.equals("Add2")
					|| what.equals("Add3") || what.equals("Add4")
					|| what.equals("Add5") || what.equals("Add6")
					|| what.equals("Add7") || what.equals("Add8")){
				Intent myIntent = new Intent(getBaseContext(), AddView.class);
				myIntent.setAction("Add" + Math.random());
				startActivityForResult(myIntent, 0);
				this.finish();
			}
			Toast.makeText(this, what, Toast.LENGTH_SHORT).show();
		} else if (predictions.size() > 0 && predictions.get(0).score > 1.0
				&& gesture.getStrokesCount() == 1) {

			String what = "";
			for (int i = 0; i < predictions.size(); i++) {
				if (predictions.get(i).name.equals("Next")
						|| predictions.get(i).name.equals("Previous")
						|| predictions.get(i).name.equals("Help")
						|| predictions.get(i).name.equals("Month2")
						|| predictions.get(i).name.equals("Month")) {
					what = predictions.get(i).name;
					break;
				}
			}
			Toast.makeText(this, what, Toast.LENGTH_SHORT).show();
			if(what.equals("Next")){
				checkGoUp();
			}else if(what.equals("Previous")){
				checkGoDown();
			}else if(what.equals("Month") || what.equals("Month2")){
				Intent myIntent = new Intent(getBaseContext(), CalendarView.class);
				startActivityForResult(myIntent, 0);
				this.finish();
			}
			else if(what.equals("Help")){
				Intent myIntent = new Intent(getBaseContext(), Help.class);
				startActivityForResult(myIntent, 0);
				this.finish();
			}
		}
	}

	public void checkGoUp(){
		cal.add(Calendar.DAY_OF_MONTH, 1);
		dayValue = cal.get(Calendar.DAY_OF_MONTH);
		monthValue = cal.get(Calendar.MONTH);
		yearValue = cal.get(Calendar.YEAR);

		Intent myIntent = new Intent(getBaseContext(), DayView.class);
		myIntent.putExtra("day", dayValue);
		myIntent.putExtra("month", monthValue);
		myIntent.putExtra("year", yearValue);
		startActivityForResult(myIntent, 0);
		this.finish();
	}

	public void checkGoDown(){
		cal.add(Calendar.DAY_OF_MONTH, -1);	
		dayValue = cal.get(Calendar.DAY_OF_MONTH);
		monthValue = cal.get(Calendar.MONTH);
		yearValue = cal.get(Calendar.YEAR);

		Intent myIntent = new Intent(getBaseContext(), DayView.class);
		myIntent.putExtra("day", dayValue);
		myIntent.putExtra("month", monthValue);
		myIntent.putExtra("year", yearValue);
		startActivityForResult(myIntent, 0);
		this.finish();
	}
	private double convertTime(long milli)
	{
		double time = 0.0;

		Calendar cal = Calendar.getInstance();
		cal.setTimeInMillis(milli);
		time = cal.get(Calendar.HOUR_OF_DAY);
		time += ( cal.get(Calendar.MINUTE) / 60.0 );

		return time;
	}

	private double convertDuration(long milli)
	{
		return ((double) milli) / MILLI_IN_HOUR;
	}

	/* Creates the menu items */
	public boolean onCreateOptionsMenu(Menu menu) {
		menu.add(0, MENU_MONTH, 0, "Month").setIcon(
				android.R.drawable.ic_menu_month);
		menu.add(0, MENU_ADD, 0, "Add").setIcon(
				android.R.drawable.ic_menu_add);
		// menu.add(0, MENU_SETTINGS, 0, "Settings").setIcon(
		// android.R.drawable.ic_menu_preferences);
		menu.add(0, MENU_SETTINGS, 0, "Settings").setIcon(
				android.R.drawable.ic_menu_preferences);
		menu.add(0, MENU_HELP, 0, "Help").setIcon(
				android.R.drawable.ic_menu_help);
		menu.add(0, MENU_EXIT, 0, "Exit").setIcon(
				android.R.drawable.ic_menu_close_clear_cancel);
		return true;
	}

	/* Handles item selections */
	public boolean onOptionsItemSelected(MenuItem item) {
		Intent myIntent;
		switch (item.getItemId()) {
		case MENU_MONTH:
			myIntent = new Intent(getBaseContext(), CalendarView.class);
			startActivityForResult(myIntent, 0);
			this.finish();
			return true;
		case MENU_ADD:
			myIntent = new Intent(getBaseContext(), AddView.class);
			startActivityForResult(myIntent, 0);
			this.finish();
			return true;
		case MENU_SETTINGS:

			return true;
		case MENU_HELP:
			myIntent = new Intent(getBaseContext(), Help.class);
			startActivityForResult(myIntent, 0);
			this.finish();
			return true;

		case MENU_EXIT:

			return true;
		}
		return false;
	}

	public int decideMonthTotal(boolean leap) {
		if (monthValue == 0 || monthValue == 2 || monthValue == 4 || monthValue == 6 || monthValue == 7
				|| monthValue == 9 || monthValue == 11) {
			return 31;
		} else if (monthValue == 1 && leap == true) {
			return 29;
		} else if (monthValue == 1 && leap == false) {
			return 28;
		} else {
			return 30;
		}
	}

}
